home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 17 / AMIGAplus Sonderheft 17 (1999)(ICP)(DE)[!].iso / Rexx / SaveAnimGif.pprx < prev    next >
Text File  |  1997-06-01  |  18KB  |  641 lines

  1. /* Personal Paint Amiga Rexx script - Copyright © 1996, 1997 Cloanto Italia srl */
  2.  
  3. /* $VER: SaveAnimGif.pprx 1.7 */
  4.  
  5. /** ENG
  6.  This script saves the current anim-brush as a GIF animation file. Specific
  7.  features of the GIF animation specification can be set through a requester.
  8.  
  9.  This script checks for the differences between frames and only stores
  10.  the smallest rectangular region containing changes. Other techniques
  11.  are employed for additional compression. The resulting GIF animations are
  12.  highly optimized and occupy considerably less space than GIF animations
  13.  created with other tools available on the Amiga.
  14.  
  15.  The "Use Loop" option inserts an "Application Extension Block" into the GIF
  16.  file (as implemented by Netscape in its Navigator software from version 2).
  17.  This additional block, which is interpreted by most other browsers
  18.  supporting GIF animations, specifies that the animation be repeated as many
  19.  times as indicated by the "Loop" value. A value of 0 expressly means
  20.  "loop continuously".
  21.  
  22.  The list of frames shows the timing value for each frame, in seconds/100.
  23.  These values can be selected, edited and applied to one or more frames.
  24.  Alternatively, the timing can be copied automatically from the current
  25.  animation. If this option is selected ("From Animation"), then the
  26.  "Delay" value is used to indicate from which animation frame the timing
  27.  values are to be copied.
  28.  
  29.  The "Transparency" setting indicates the current transparency status of
  30.  the anim-brush. If transparency is not required by the animation, it is
  31.  recommended to leave this option disabled.
  32.  
  33.  Note: an "anim-brush" is a part of a full-screen animation. It can be
  34.  either loaded or defined manually after clicking three times on the
  35.  Define Brush tool.
  36. */
  37.  
  38. /** DEU
  39.  Dieses Skript dient zum Speichern des aktuellen Anim-Brushes als
  40.  GIF-Animation. Eine Reihe spezifischer Merkmale des Animationsformats läßt
  41.  sich in einem dazugehörigen Dialogfenster auswählen.
  42.  
  43.  Nach der Skriptausführung werden zwei aufeinanderfolgende Frames zunächst
  44.  auf Unterschiede untersucht. Gespeichert wird dann nur der kleinste
  45.  rechteckige Bereich, der Unterschiede zwischen den beiden Bildern aufweist.
  46.  Außerdem werden zum Erzielen einer weiter verbesserten Komprimierung noch
  47.  andere Verfahren angewendet. Die daraus resultierenden hochoptimierten
  48.  GIF-Animationen benötigen erheblich weniger Speicherplatz als solche, die
  49.  mit anderen für den Amiga erhältlichen Tools erstellt worden sind.
  50.  
  51.  Durch die Option "Schleife aktiv:" wird der GIF-Datei eine
  52.  Programmerweiterung ("Application Extension Block") hinzugefügt, wie sie von
  53.  Netscape im Navigator ab Version 2 implementiert ist. Dieser auch von den
  54.  meisten anderen Browsern, die GIF-Animationen unterstützen, interpretierte
  55.  Block legt fest, daß die Animation so oft wiederholt wird, wie unter
  56.  "Schleife:" angegeben. Ein Wert von 0 bewirkt das Abspielen in einer
  57.  Endlosschleife.
  58.  
  59.  Die Frameliste zeigt den Timingwert für jedes Einzelbild in Hundertstel
  60.  Sekunden. Diese Werte lassen sich auswählen, bearbeiten und anschließend
  61.  einem oder mehreren Einzelbildern zuweisen. Alternativ dazu können die
  62.  Timingwerte automatisch aus der aktuellen Animation kopiert werden. Wenn die
  63.  entsprechende Option aktiviert ist ("Von Animation"), wird der
  64.  "Verzögerung"-Wert verwendet, um anzuzeigen, von welchem Einzelbild der
  65.  Animation die Timingwerte kopiert werden sollen.
  66.  
  67.  Die "Transparenz"-Einstellung gibt den aktuellen Transparenzstatus des
  68.  Animationspinsels wieder. Erfordert die Animation keine Transparenz, so wird
  69.  empfohlen, diese Option ausgeschaltet zu lassen.
  70.  
  71.  Hinweis: Ein Animationspinsel ist ein Bestandteil einer normalen Animation.
  72.  Er läßt sich nach einem Dreifachklick auf das Pinseldefinitionswerkzeug
  73.  entweder laden oder manuell definieren.
  74. */
  75.  
  76. /** ITA
  77.  Questo script salva l'anim-brush corrente come un'animazione GIF. Si possono
  78.  impostare le caratteristiche peculiari di una animazione GIF tramite una
  79.  apposita finestra di dialogo.
  80.  
  81.  Questo script controlla eventuali differenze tra fotogrammi e salva solo
  82.  la più piccola regione rettangolare che contiene modifiche. Altre tecniche
  83.  sono utilizzate per una compressione aggiuntiva. Le animazioni GIF risultanti
  84.  sono altamente ottimizzate ed occupano molto meno spazio di quelle create con
  85.  altri programmi disponibili su Amiga.
  86.  
  87.  L'opzione "Usare ciclo" inserisce un "Application Extension Block" nel file GIF
  88.  (come implementato da Netscape nel suo programma Navigator a partire dalla
  89.  versione 2). Questo blocco aggiuntivo, che viene interpretato dalla maggior
  90.  parte degli altri programmi di navigazione che permettono l'uso di animazioni
  91.  GIF, specifica che l'animazione deve essere ripetuta tante volte quante
  92.  indicato dal valore "Ciclo". Un valore pari a 0 significa espressamente
  93.  "ciclo continuo".
  94.  
  95.  L'elenco dei fotogrammi mostra il valore di temporizzazione per ciascun
  96.  fotogramma, in centesimi di secondo. Tali valori possono essere selezionati,
  97.  modificati e applicati a uno o più fotogrammi. In alternativa, la
  98.  temporizzazione può essere copiata automaticamente dall'animazione corrente.
  99.  Se questa opzione è attiva ("Da animazione"), si usa il valore di
  100.  "Temporizzazione fotogrammi" per indicare da quale fotogramma dell'animazione
  101.  si devono copiare i valori di temporizzazione.
  102.  
  103.  L'impostazione di "Trasparenza" indica lo stato attuale della trasparenza
  104.  dell'anim-brush. Se l'animazione non richiede la trasparenza, è consigliabile
  105.  lasciare disattivata questa opzione.
  106.  
  107.  Nota: un "anim-brush" è un pennello, e come tale in genere una (più piccola)
  108.  parte di un'animazione a tutto schermo. Un anim-brush può essere caricare,
  109.  oppure definito manualmente facendo click tre volte sullo strumento
  110.  Definire pennello.
  111. */
  112.  
  113. IF ARG(1, EXISTS) THEN
  114.     PARSE ARG PPPORT
  115. ELSE
  116.     PPPORT = 'PPAINT'
  117.  
  118. IF ~SHOW('P', PPPORT) THEN DO
  119.     IF EXISTS('PPaint:PPaint') THEN DO
  120.         ADDRESS COMMAND 'Run >NIL: PPaint:PPaint'
  121.         DO 30 WHILE ~SHOW('P',PPPORT)
  122.              ADDRESS COMMAND 'Wait >NIL: 1 SEC'
  123.         END
  124.     END
  125.     ELSE DO
  126.         SAY "Personal Paint could not be loaded."
  127.         EXIT 10
  128.     END
  129. END
  130.  
  131. IF ~SHOW('P', PPPORT) THEN DO
  132.     SAY 'Personal Paint Rexx port could not be opened'
  133.     EXIT 10
  134. END
  135.  
  136. ADDRESS VALUE PPPORT
  137. OPTIONS RESULTS
  138. OPTIONS FAILAT 10000
  139.  
  140. Get 'LANG'
  141. IF RESULT = 1 THEN DO        /* Deutsch */
  142.     txt_title_req     = 'GIF-Anim-Brush speichern'
  143.     txt_title_set     = 'GIF-Anim-Brush-Einstellungen'
  144.     txt_title_delay   = 'Frame-Verzögerung'
  145.     txt_gad_delay     = 'Frame-Verzögerungen:'
  146.     txt_gad_annot     = '_Bemerkung:'
  147.     txt_gad_loop      = '_Schleife:'
  148.     txt_gad_useloop   = 'Schleife ak_tiv:'
  149.     txt_gad_transp    = '_Transparenz:'
  150.     txt_gad_del       = '_Verzögerung:'
  151.     txt_gad_deltype   = ' '
  152.     txt_gad_deltype0  = '1/100\""'
  153.     txt_gad_deltype1  = 'Von Animation'
  154.     txt_gad_from      = 'A_b Frame:'
  155.     txt_gad_to        = 'Bi_s Frame:'
  156.     txt_err_oldclient = 'Für dieses Skript_ist eine neuere Version_von Personal Paint erforderlich'
  157.     txt_err_oldlib    = 'Für dieses Skript ist eine neuere Version_der GIF library erforderlich'
  158.     txt_err_notabsh   = 'Aktueller Brush_ist kein Anim-Brush'
  159.     txt_err_notemp    = 'Zu wenig Speicher_für temporären Brush'
  160.     txt_err_nomem     = 'Speichermangel'
  161.     txt_err_nosave    = 'Fehler bei Datei-Ein-/Ausgabe'
  162. END
  163. ELSE IF RESULT = 2 THEN DO    /* Italiano */
  164.     txt_title_req     = 'Scrivere Anim-brush GIF'
  165.     txt_title_set     = 'Parametri Anim-brush GIF'
  166.     txt_title_delay   = 'Temporizzazione'
  167.     txt_gad_delay     = 'Temporizzazione fotogrammi:'
  168.     txt_gad_annot     = '_Note:'
  169.     txt_gad_loop      = 'Cic_lo:'
  170.     txt_gad_useloop   = '_Usare ciclo:'
  171.     txt_gad_transp    = '_Transparenza:'
  172.     txt_gad_del       = '_Temporizzazione:'
  173.     txt_gad_deltype   = ' '
  174.     txt_gad_deltype0  = '1/100\""'
  175.     txt_gad_deltype1  = 'Da animazione'
  176.     txt_gad_from      = 'Da _fotogramma:'
  177.     txt_gad_to        = 'A f_otogramma:'
  178.     txt_err_oldclient = 'Questa procedura richiede_una versione più recente_di Personal Paint'
  179.     txt_err_oldlib    = 'Questa procedura richiede_una versione più recente_della libreria GIF'
  180.     txt_err_notabsh   = 'Il pennello attuale_non è un anim-brush'
  181.     txt_err_notemp    = 'Impossibile creare_pennello temporaneo'
  182.     txt_err_nomem     = 'Memoria insufficiente'
  183.     txt_err_nosave    = 'Errore di scrittura'
  184. END
  185. ELSE DO                /* English */
  186.     txt_title_req     = 'Save GIF Anim-Brush'
  187.     txt_title_set     = 'GIF Anim-Brush Settings'
  188.     txt_title_delay   = 'Frame Delay'
  189.     txt_gad_delay     = 'Frame Delays:'
  190.     txt_gad_annot     = '_Annotation:'
  191.     txt_gad_loop      = '_Loop:'
  192.     txt_gad_useloop   = '_Use Loop:'
  193.     txt_gad_transp    = '_Transparency:'
  194.     txt_gad_del       = '_Delay:'
  195.     txt_gad_deltype   = ' '
  196.     txt_gad_deltype0  = '1/100\""'
  197.     txt_gad_deltype1  = 'From Animation'
  198.     txt_gad_from      = '_From Frame:'
  199.     txt_gad_to        = 'T_o Frame:'
  200.     txt_err_oldclient = 'This script requires a newer_version of Personal Paint'
  201.     txt_err_oldlib    = 'This script requires a newer_version of the GIF library'
  202.     txt_err_notabsh   = 'The current brush_is not an anim-brush'
  203.     txt_err_notemp    = 'No space for temporary brush'
  204.     txt_err_nomem     = 'Not enough memory'
  205.     txt_err_nosave    = 'File I/O error'
  206. END
  207.  
  208. Version 'REXX'
  209. IF RESULT < 7 THEN DO
  210.     RequestNotify 'PROMPT "'txt_err_oldclient'"'
  211.     EXIT 10
  212. END
  213.  
  214. LockGUI
  215. GetBrushAttributes 'FRAMES'
  216. frames = RESULT
  217.  
  218. IF frames < 2 THEN DO
  219.     RequestNotify 'PROMPT "'txt_err_notabsh'"'
  220.     UnlockGUI
  221.     EXIT 0
  222. END
  223.  
  224. GetBrushNumber
  225. bshnum = RESULT
  226.  
  227. SetCurrentBrush 'UNUSED'
  228. IF RC ~= 0 THEN DO
  229.     RequestNotify 'PROMPT "'txt_err_notemp'"'
  230.     UnlockGUI
  231.     EXIT 0
  232. END
  233. GetBrushNumber
  234. tbshnum = RESULT
  235.  
  236. SetCurrentBrush 'BRUSH' bshnum
  237. GetBrushInfo 'ANNOTATION'
  238. frame_annot = RESULT
  239.  
  240. loop = -1
  241. delay. = 0
  242. IF WORD(frame_annot, 1) = 'LOOP' & WORD(frame_annot, 3) = 'DELAY' THEN DO
  243.     loop = WORD(frame_annot, 2)
  244.     IF ~DATATYPE(loop, 'W') THEN
  245.         loop = -1
  246.     DO frm = 1 TO frames
  247.         del = WORD(frame_annot, 3+frm)
  248.         IF DATATYPE(del, 'W') THEN
  249.             delay.frm = del
  250.     END
  251. END
  252. use_loop = (loop >= 0)
  253. IF loop < 0 THEN
  254.     loop = 0
  255.  
  256. fnlen = LENGTH(frames)
  257. dsel = 1
  258. do_req = 1
  259. deltype = 0
  260.  
  261. GetBrushInfo 'COPYRIGHT'
  262. annot = RESULT
  263. max_annot_size = LENGTH(annot) * 2
  264. IF max_annot_size < 200 THEN
  265.     max_annot_size = 200
  266.  
  267. GetBrushAttributes 'TRANSPARENCY'
  268. transp = RESULT
  269. IF transp ~= 1 THEN
  270.     transp = 0
  271.  
  272. DO WHILE do_req
  273.     ppos = 1
  274.     DO FOREVER
  275.         ppos = INDEX(annot, '"', ppos)
  276.         IF ppos = 0 THEN BREAK
  277.         annot = INSERT('\"', annot, ppos-1)
  278.         ppos = ppos + 3
  279.     END
  280.  
  281.     req = '"LIST ACTION = ""'txt_gad_delay'"", 'frames', 'dsel-1', 20, 7'
  282.     DO frm = 1 TO frames
  283.         req = req || ', ""'RIGHT(frm, fnlen) || ':' delay.frm || '""'
  284.     END
  285.  
  286.     req = req ||,
  287.       ' STRING = ""'txt_gad_annot'"", 'max_annot_size', ""'annot'"" ' ||,
  288.         ' INTSTR = ""'txt_gad_loop'"", 0, 32767, 'loop' ' ||,
  289.         ' CHECK = ""'txt_gad_useloop'"", 'use_loop' ' ||,
  290.         ' CHECK = ""'txt_gad_transp'"", 'transp' "'
  291.  
  292.     Request 'RESIZE "'txt_title_set'"' req
  293.     IF RC = 0 THEN DO
  294.         dsel  = RESULT.1 + 1
  295.         annot = RESULT.2
  296.         loop  = RESULT.3
  297.         use_loop = RESULT.4
  298.         transp = RESULT.5
  299.  
  300.         IF RESULT = -1 THEN DO
  301.             Request '"'txt_title_delay'" ' ||,
  302.                         '"INTSTR = ""'txt_gad_del'"", 0, 32767, 'delay.dsel' ' ||,
  303.                         ' CYCLE = ""'txt_gad_deltype'"", 2, 'deltype', ""'txt_gad_deltype0'"", ""'txt_gad_deltype1'"" ' ||,
  304.                         ' SEPARATOR ' ||,
  305.                         ' INTSTR = ""'txt_gad_from'"", 1, 'frames', 'dsel' ' ||,
  306.                         ' INTSTR = ""'txt_gad_to'"", 1, 'frames', 'dsel' "'
  307.             IF RC = 0 THEN DO
  308.                 del     = RESULT.1
  309.                 deltype = RESULT.2
  310.                 frfrom  = RESULT.3
  311.                 frto    = RESULT.4
  312.                 frstep  = SIGN(frto - frfrom)
  313.                 IF frstep = 0 THEN
  314.                     frstep = 1
  315.                 DO frm = frfrom TO frto BY frstep
  316.                     IF deltype THEN DO
  317.                         IF del < 1 THEN
  318.                             del = 1
  319.                         GetFrameDelay 'FRAME' del
  320.                         IF RC = 0 THEN
  321.                             delay.frm = TRUNC((RESULT * 100 / 60) + 0.5)
  322.                         del = del + frstep
  323.                     END
  324.                     ELSE delay.frm = del
  325.                 END
  326.             END
  327.         END
  328.         ELSE do_req = 0
  329.     END
  330.     ELSE DO
  331.         UnlockGUI
  332.         EXIT 0
  333.     END
  334. END
  335.  
  336. IF ~use_loop THEN
  337.     loop = -1
  338. frame_annot = 'LOOP' loop 'DELAY'
  339. DO frm = 1 TO frames
  340.     frame_annot = frame_annot delay.frm
  341. END
  342. SetBrushInfo 'ANNOTATION "'frame_annot'"'
  343.  
  344.  
  345. RequestFile '"'txt_title_req'" SAVEMODE'
  346. IF RC = 0 THEN DO
  347.     PARSE VALUE RESULT WITH '"' fname '"'
  348.     tempfile = 'T:PP_AnGif.'PRAGMA('ID')
  349.  
  350.     GetBrushAttributes 'FRAMEFIRST'
  351.     sv_frmin = RESULT
  352.     GetBrushAttributes 'FRAMELAST'
  353.     sv_frmax = RESULT
  354.     GetBrushAttributes 'LENGTH'
  355.     sv_frlen = RESULT
  356.     GetBrushAttributes 'FRAMEPOSITION'
  357.     sv_frpos = RESULT
  358.     Get 'ICONS'
  359.     sv_icons = RESULT
  360.  
  361.     GetBrushAttributes 'WIDTH'
  362.     bwidth = RESULT
  363.     GetBrushAttributes 'HEIGHT'
  364.     bheight = RESULT
  365.  
  366.     GetBrushAttributes 'TRANSPARENTCOLOR'
  367.     transpcol = RESULT
  368.     GetBrushAttributes 'COLORS'
  369.     bcolors = RESULT
  370.     plt_size = bcolors * 3
  371.  
  372.     Get 'PATHBSH'
  373.     PARSE VAR RESULT '"' sv_pathbsh '"'
  374.  
  375.     IF transp = 1 THEN
  376.         pckinfo = '09'x
  377.     ELSE
  378.         pckinfo = '00'x
  379.  
  380.     DO bdepth = 1 TO 8
  381.         IF bcolors = (2 ** bdepth) THEN
  382.             BREAK
  383.     END
  384.  
  385.     tbmap.0 = 0
  386.     tbmap.1 = 0
  387.     tbnum = 0
  388.     gfile_open = 0
  389.     global_plt = ''
  390.     err_msg = ''
  391.  
  392.     SIGNAL ON Break_C
  393.  
  394.     AllocateBitmap bwidth bheight bdepth
  395.     IF RC = 0 THEN DO
  396.         tbmap.0 = RESULT
  397.  
  398.         AllocateBitmap bwidth bheight bdepth
  399.         IF RC = 0 THEN DO
  400.             tbmap.1 = RESULT
  401.  
  402.             SetBrushAttributes 'FRAMEFIRST 1 FRAMELAST' frames 'LENGTH' frames
  403.             Set '"ICONS = 0"'
  404.  
  405.             DO frm = 1 TO frames
  406.                 SetCurrentBrush 'BRUSH' bshnum
  407.                 IF RC ~= 0 THEN DO
  408.                     err_msg = txt_err_nomem
  409.                     BREAK
  410.                 END
  411.  
  412.                 SetBrushAttributes 'FRAMEPOSITION' frm
  413.                 IF RC ~= 0 THEN DO
  414.                     err_msg = txt_err_nomem
  415.                     BREAK
  416.                 END
  417.  
  418.                 GetBitmap '0 0 BITMAP' tbmap.tbnum 'FROMBRUSH'
  419.                 tbnum = 1 - tbnum
  420.  
  421.                 GetBrushColors
  422.                 local_plt = RESULT
  423.  
  424.                 IF frm = 1 THEN DO
  425.                     dx0 = 0
  426.                     dy0 = 0
  427.                     dx1 = bwidth - 1
  428.                     dy1 = bheight - 1
  429.                     global_plt = local_plt
  430.                 END
  431.                 ELSE DO
  432.                     IF transp = 1 THEN
  433.                         GetBrushAttributes 'BOUNDARIES'
  434.                     ELSE
  435.                         GetBitmapDelta tbmap.0 tbmap.1
  436.  
  437.                     PARSE VAR RESULT dx0 dy0 dx1 dy1 .
  438.                     IF dx0 < 0 THEN DO
  439.                         dx0 = 0
  440.                         dy0 = 0
  441.                         dx1 = 0
  442.                         dy1 = 0
  443.                     END
  444.                     IF transp ~= 1 & global_plt ~== local_plt THEN DO        /* IExplorer bug */
  445.                         dx0 = 0
  446.                         dy0 = 0
  447.                         dx1 = bwidth - 1
  448.                         dy1 = bheight - 1
  449.                     END
  450.                 END
  451.  
  452.                 SetCurrentBrush 'BRUSH' tbshnum
  453.                 IF RC ~= 0 THEN DO
  454.                     err_msg = txt_err_nomem
  455.                     BREAK
  456.                 END
  457.  
  458.                 CopyBrush bshnum dx0 dy0 dx1 dy1 'NOFRAMES'
  459.                 IF RC ~= 0 THEN DO
  460.                     err_msg = txt_err_nomem
  461.                     BREAK
  462.                 END
  463.  
  464.                 SaveBrush tempfile 'FORCE QUIET NOPROGRESS FORMAT "GIF" OPTIONS "GIF89=1" "PROGDSP=0" "SCRFMT=0"'
  465.                 IF RC ~= 0 THEN DO
  466.                     IF RC = 46 | RC = 47 THEN
  467.                         err_msg = txt_err_oldlib
  468.                     ELSE
  469.                         err_msg = txt_err_nosave
  470.                     BREAK
  471.                 END
  472.  
  473.                 IF ~OPEN('tfile', tempfile, 'R') THEN DO
  474.                     err_msg = txt_err_nosave
  475.                     BREAK
  476.                 END
  477.  
  478.                 IF frm = 1 THEN DO
  479.                     IF ~OPEN('gfile', fname, 'W') THEN DO
  480.                         err_msg = txt_err_nosave
  481.                         BREAK
  482.                     END
  483.                     gfile_open = 1
  484.                     data = READCH('tfile', 13)        /* sign + screen descriptor */
  485.                     bxpix = BITOR(BITAND(SUBSTR(data, 11, 1), '07'x), '80'x)
  486.                     CALL WRITECH('gfile', data)
  487.  
  488.                     plt_data = READCH('tfile', plt_size)    /* palette */
  489.                     CALL WRITECH('gfile', plt_data)
  490.                     do_plt = 0
  491.  
  492.                     IF use_loop THEN
  493.                         CALL WRITECH('gfile', '21FF0B'x || 'NETSCAPE2.0' || '0301'x || IntelWord(loop) || '00'x)
  494.  
  495.                     IF annot ~= '' THEN DO        /* annotation */
  496.                         CALL WRITECH('gfile', '21FE'x)
  497.                         alen = LENGTH(annot)
  498.                         apos = 1
  499.                         DO WHILE alen > 0
  500.                             IF alen <= 255 THEN
  501.                                 aln = alen
  502.                             ELSE
  503.                                 aln = 255
  504.                             CALL WRITECH('gfile', D2C(aln) || SUBSTR(annot, apos, aln))
  505.                             apos = apos + aln
  506.                             alen = alen - aln
  507.                         END
  508.                         CALL WRITECH('gfile', '00'x)
  509.                     END
  510.                 END
  511.                 ELSE DO
  512.                     CALL SEEK('tfile', 13, 'B')
  513.                     plt_data = READCH('tfile', plt_size)
  514.                     do_plt = (global_plt ~== local_plt)
  515.                 END
  516.  
  517.                 DO FOREVER
  518.                     code = READCH('tfile', 1)
  519.  
  520.                     IF code = ',' THEN DO    /* image */
  521.                         /* gfx control */
  522.                         CALL WRITECH('gfile', '21F904'x || pckinfo || IntelWord(delay.frm) || D2C(transpcol) || '00'x)
  523.  
  524.                         data = READCH('tfile', 9)        /* Get image descriptor */
  525.                         imginfo = SUBSTR(data, 9, 1)
  526.                         IF do_plt THEN
  527.                             imginfo = BITOR(BITAND(imginfo, '40'x), bxpix)
  528.  
  529.                         /* image descriptor */
  530.                         CALL WRITECH('gfile', ',' || IntelWord(dx0) || IntelWord(dy0) || IntelWord(dx1-dx0+1) || IntelWord(dy1-dy0+1) || imginfo)
  531.  
  532.                         IF do_plt THEN
  533.                             CALL WRITECH('gfile', plt_data)
  534.  
  535.                         tpos = SEEK('tfile', 0, 'C')
  536.                         epos = SEEK('tfile', 0, 'E')
  537.                         dsize = epos - tpos - 1
  538.                         CALL SEEK('tfile', tpos, 'B')
  539.  
  540.                         /* image data */
  541.                         DO WHILE dsize > 0
  542.                             IF dsize > 65000 THEN
  543.                                 tsize = 65000
  544.                             ELSE
  545.                                 tsize = dsize
  546.                             data = READCH('tfile', tsize)
  547.                             CALL WRITECH('gfile', data)
  548.                             dsize = dsize - tsize
  549.                         END
  550.                         BREAK
  551.                     END
  552.                     ELSE IF code = '!' THEN DO        /* extension */
  553.                         CALL SEEK('tfile', 1, 'C')
  554.                         length = 1
  555.                         DO WHILE length ~= 0
  556.                             length = C2D(READCH('tfile', 1))
  557.                             IF length > 0 THEN
  558.                                 CALL SEEK('tfile', length, 'C')
  559.                         END
  560.                     END
  561.                     ELSE BREAK
  562.                 END
  563.  
  564.                 CALL CLOSE('tfile')
  565.             END
  566.  
  567.             CALL WRITECH('gfile', ';')
  568.             CALL CLOSE('gfile')
  569.             gfile_open = 0
  570.  
  571.             ADDRESS COMMAND 'Delete >NIL: 'tempfile
  572.  
  573.             SetCurrentBrush 'BRUSH' tbshnum
  574.             IF RC = 0 THEN
  575.                 FreeBrush 'FORCE'
  576.  
  577.             SetCurrentBrush 'BRUSH' bshnum
  578.             IF RC = 0 THEN
  579.                 SetBrushAttributes 'FRAMEFIRST' sv_frmin 'FRAMELAST' sv_frmax 'LENGTH' sv_frlen 'FRAMEPOSITION' sv_frpos
  580.  
  581.             Set '"ICONS =' sv_icons '"'
  582.  
  583.             FreeBitmap tbmap.1
  584.         END
  585.         ELSE err_msg = txt_err_nomem
  586.  
  587.         FreeBitmap tbmap.0
  588.     END
  589.     ELSE err_msg = txt_err_nomem
  590.  
  591.     IF err_msg ~= '' THEN
  592.         RequestNotify 'PROMPT "'err_msg'"'
  593.  
  594.     Set '"PATHBSH=""'sv_pathbsh'"" "'
  595. END
  596. UnlockGUI
  597.  
  598. EXIT 0
  599.  
  600.  
  601.  
  602.  
  603. IntelWord: PROCEDURE
  604.  
  605.     value = ARG(1)
  606.  
  607.     hibyte = value % 256
  608.     lobyte = value - (hibyte * 256)
  609.  
  610.     RETURN D2C(lobyte) || D2C(hibyte)
  611.  
  612.  
  613.  
  614.  
  615. Break_C:
  616.  
  617.     IF gfile_open THEN
  618.         CALL CLOSE('gfile')
  619.  
  620.     ADDRESS COMMAND 'Delete >NIL: 'tempfile
  621.  
  622.     SetCurrentBrush 'BRUSH' tbshnum
  623.     IF RC = 0 THEN
  624.         FreeBrush 'FORCE'
  625.  
  626.     SetCurrentBrush 'BRUSH' bshnum
  627.     IF RC = 0 THEN
  628.         SetBrushAttributes 'FRAMEFIRST' sv_frmin 'FRAMELAST' sv_frmax 'LENGTH' sv_frlen 'FRAMEPOSITION' sv_frpos
  629.  
  630.     Set '"ICONS =' sv_icons '"'
  631.  
  632.     IF tbmap.1 ~= 0 THEN
  633.         FreeBitmap tbmap.1
  634.  
  635.     IF tbmap.0 ~= 0 THEN
  636.         FreeBitmap tbmap.0
  637.  
  638.     Set '"PATHBSH=""'sv_pathbsh'"" "'
  639.  
  640.     RETURN
  641.